
/*
    Software License

    Copyright (C) 2021-05-24  Xoronos

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, version 3.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

/*
    Liabilities

    The software is provided "AS IS" without any warranty of any kind, either expressed,
    implied, or statutory, including, but not limited to, any warranty that the software
    will conform to specifications, any implied warranties of merchantability, fitness
    for a particular purpose, and freedom from infringement, and any warranty that the
    documentation will conform to the software, or any warranty that the software will
    be error free.

    In no event shall Xoronos be liable for any damages, including, but not limited to,
    direct, indirect, special or consequential damages, arising out of, resulting from,
    or in any way connected with this software, whether or not based upon warranty,
    contract, tort, or otherwise, whether or not injury was sustained by persons or
    property or otherwise, and whether or not loss was sustained from, or arose out of
    the results of, or use of, the software or services provided hereunder.

    To request the provided software under a different license you can contact us at
    support@xoronos.com
*/

#include <stdio.h>
#include "examples.h"
#include "xrn_miners.h"
#include "xrn_core.h"

    /////////////////////////////////////////////////////
    //                   Introduction                  //
    /////////////////////////////////////////////////////
    // This code example shows how to generate         //
    // decompressed Xoron matrices, which are used to  //
    // generate pseudo-random numbers used in all the  //
    // cryptographic function.                         //
    //                                                 //
    // In modular cryptography users are encoraged to  //
    // mine Xoron matrices to privately perform        //
    // non-standard cryptography.                      //
    /////////////////////////////////////////////////////

    /////////////////////////////////////////////////////
    //                   Pre-requisits                 //
    /////////////////////////////////////////////////////
    // No pre-requisites are reqired to run the        //
    // provided example.                               //
    /////////////////////////////////////////////////////

int generate_xrn_matrix_all_rnd(
 )
{

    //////////////////////////
    // Variable definitions //
    //////////////////////////

    FILE *compressed_xmatrix_fp;
    FILE *decompressed_xmatrix_fp;

    // miner all rnd parameters

    float prob;                 // probability of each bit to be 1 in genesis base

    // maximum numbers of tries for the miner

    unsigned max_try;

    // use either true randomness of deterministic randomness
    // if mining_mode = 0 |-> true randomness, if mining_mode = 1 |-> pseudo randomness

    uint8_t mining_mode;

    // Xoron matrix representations
    //
    // The Xoron matrix compressed is the output of the mining process.
    // It needs to be decompressed to be used in security algorithms.
    // Users can permute the Xoron matrix compressed data-structure to derive
    // many Xoron matrices.

    xrn_matrix_compressed_t xmc;

    // The Xoron matrix is the modular part of Xoron cryptography, and therefore
    // it is used directly to perform cryptography.
    // The Xoron matrix is derived from a Xoron matrix comrpessed data structure. 

    xrn_matrix_t *xm;

    // The encoding settings are used to load or store file produced by the Xoron
    // cryptography

    xrn_crypto_extra_settings_t settings;

    // settings.encoding_settings.i/o_settings the input and output settings
    // i/o_settings.mode = (std_parameters/xrn_parameters/std_parameters_plus_password/xrn_parameters_plus_password)
    //                     std_parameters the compiled settings
    //                     xrn_parameters the settings coming from a file
    //                     std_parameters_plus_password compiled parameters with a password
    //                     xrn_parameters_plus_password file parameters with a password
    // i/o_settings.encoding_parameters_fp file pointer if mode is ( xrn_parameters/xrn_parameters_plus_password )
    // i/o_settings.password[XRN_ENC_PASS_BUFF_SIZE] password string if mode is ( xrn_parameters_plus_password/std_parameters_plus_password )
    // i/o_settings.password_length the password length if the mode is ( xrn_parameters_plus_password/std_parameters_plus_password )

    /////////////
    // Logging //
    /////////////

    // Set the default logging file streams
    // errors -> stderr
    // warnings -> stdout
    // notifications -> stdout
    // debug -> stdout

    xrn_set_default_log(  );

    // To change the default logging you can use the functions below,
    // where fp is the opened file pointer
    // 
    // xrn_change_error_log( fp )
    // xrn_change_warning_log( fp )
    // xrn_change_notification_log( fp )
    // xrn_change_debug_log( fp )

    /////////////////////////////
    // Variable initialization //
    /////////////////////////////

    compressed_xmatrix_fp = fopen( "xrn_matrix_compressed.xmc", "wb" );
    if ( compressed_xmatrix_fp == NULL ) {
        return -1;
    }

    // set the maximum number of tries
    max_try = 50000;

    // set prob with default settings
    xrn_mine_random_settings( &prob, 0 );

    // set the mode equal to true randomness
    mining_mode = 0;

    ////////////
    // Mining //
    ////////////

    // use standard settings without a password to load/store Xoron files
    settings.encoding_settings.i_settings.mode = std_parameters;
    settings.encoding_settings.i_settings.check_mode = xrn_automatic;
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    printf( "mining... \n" );
    if ( XSUCCESS != xrn_mine_random_wrapper( compressed_xmatrix_fp,    // destination file
                                              prob,     // probability of each bit to be 1 in genesis base
                                              max_try,  // maximum number of rounds
                                              mining_mode,      // the type of randomness
                                              NULL,     // the file pointer to the seed is pseudo_rnd
                                              settings  // the encoding interface
          ) ) {
        fclose( compressed_xmatrix_fp );
        return -1;
    }

    fclose( compressed_xmatrix_fp );

    // to perform a deterministic mining
    //
    // mining_mode = pseudo_rnd;
    // seed_fp = fopen( "xnum.xf", "rb" );
    //
    // if ( XSUCCESS != xrn_mine_random_wrapper( compressed_xmatrix_fp,
    //                                         prob,
    //                                         max_try,
    //                                         mining_mode,
    //                                         seed_fp,
    //                                         settings
    //       ) ) {
    //     fclose( compressed_xmatrix_fp );
    //     fclose( seed_fp );
    //     return -1;
    // }

    //////////////////////////////
    // Decompressing the matrix //
    //////////////////////////////

    // use standard settings without a password to load Xoron files
    settings.encoding_settings.i_settings.mode = std_parameters;

    compressed_xmatrix_fp = fopen( "xrn_matrix_compressed.xmc", "rb" );
    decompressed_xmatrix_fp = fopen( "xrn_matrix.xm", "wb" );

    if ( ( compressed_xmatrix_fp == NULL ) || ( decompressed_xmatrix_fp == NULL ) ) {
        return -1;
    }

    if ( XSUCCESS != xrn_load_matrix_compressed( compressed_xmatrix_fp, &xmc, settings ) ) {
        fclose( compressed_xmatrix_fp );
        fclose( decompressed_xmatrix_fp );
        return -1;
    }

    // It is possible to permute the Xoron matrix compressed 
    // to generate (in a fast way) many different Xoron matrices
    //
    // if ( XSUCCESS != xrn_matrix_compressed_permute( &xmc )){
    //    fclose( decompressed_xmatrix_fp);
    //    fclose( compressed_xmatrix_fp);
    //    return -1;
    // }

    xm = ( xrn_matrix_t * ) malloc( sizeof( xrn_matrix_t ) );
    if ( xm == NULL ) {
        fclose( compressed_xmatrix_fp );
        fclose( decompressed_xmatrix_fp );
        return -1;
    }

    printf( "decompressing... \n" );
    xrn_matrix_decompress( &xmc, xm );

    ///////////////////////////////////////
    // Storing the Xoron matrix and quit //
    ///////////////////////////////////////

    // use standard settings without a password to dump Xoron files
    settings.encoding_settings.o_settings.mode = std_parameters;
    settings.encoding_settings.o_settings.check_mode = xrn_automatic;

    if ( XSUCCESS != xrn_dump_matrix( xm, decompressed_xmatrix_fp, settings ) ) {
        free( xm );
        fclose( compressed_xmatrix_fp );
        fclose( decompressed_xmatrix_fp );
        return -1;
    }

    free( xm );
    if ( ( 0 != fclose( compressed_xmatrix_fp ) ) || ( 0 != fclose( decompressed_xmatrix_fp ) ) ) {
        return -1;
    }

    printf( "Xoron matrix successfully created\n" );
    return 0;

}

